package com.learn.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.learn.entity.Category;
import com.learn.entity.Question;
import com.learn.mapper.CategoryMapper;
import com.learn.mapper.QuestionMapper;
import com.learn.service.CategoryService;
import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Slf4j
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper,Category> implements CategoryService {


    @Autowired
    private QuestionMapper questionMapper;

    /**
     * 查询分类列表同时查询分类的题目数量
     * @return
     */
    @Override
    public List<Category> getAllCategories() {
        //1、查询所有分类信息集合（单表操作）
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(Category::getSort); // Sort正序排序查询
        List<Category> categoryList = list(queryWrapper); //少了count

        //2.QuestionMapper定义查询category_id 进行分组，并且统计每个分类下的count
        // [ map { category_id:14 , count:1 }]
        List<Map<String,Long>> mapList = questionMapper.selectCategoryQuestionCount();
        //3.题目查询的分类的题目数量赋值给分类集合
        Map<Long,Long>  countMap = mapList.stream().collect(Collectors.toMap(m -> m.get("category_id"), m -> m.get("count")));

        for ( Category category: categoryList) {
            Long id = category.getId();
//            // 时间复杂度 O(n)
//            for ( Map<String,Long > longMap : mapList ) {
//                Long categoryId = longMap.get( "category_id");
//                if ( id==categoryId ) {
//                    category.setCount( longMap.get("count"));
//                }
//            }
            category.setCount( countMap.getOrDefault( id, 0L) );
        }
        //4.返回对应的查询集合即可
        return  categoryList;

    }

    @Override
    public List<Category> findCategoryTreeList() {
        //1、查询所有分类信息集合（单表操作）
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(Category::getSort); // Sort正序排序查询
        List<Category> categoryList = list(queryWrapper); //少了count

        //2.QuestionMapper定义查询category_id 进行分组，并且统计每个分类下的count
        // [ map { category_id:14 , count:1 }]
        List<Map<String,Long>> mapList = questionMapper.selectCategoryQuestionCount();
        //3.题目查询的分类的题目数量赋值给分类集合
        Map<Long,Long>  countMap = mapList.stream().collect(Collectors.toMap(m -> m.get("category_id"), m -> m.get("count")));

        for ( Category category: categoryList) {
            Long id = category.getId();
            category.setCount( countMap.getOrDefault( id, 0L) );
        }
        //4.分类信息进行分组 (parent_uid）stream分组
        // key->parent   value->子分类
        Map<Long,List<Category>> longListMap= categoryList.stream().collect(Collectors.groupingBy(Category::getParentId));

        //5.筛选分类信息
        List<Category> parentCategoryList = categoryList.stream().filter(c -> c.getParentId() == 0).collect(Collectors.toList());

        //6.给一级分类循环，获取子分类，并且计算count
        for (Category parentCategory : parentCategoryList) {
            List<Category> sonCategoryList = longListMap.getOrDefault(parentCategory.getId(),new ArrayList<>());
            parentCategory.setChildren( sonCategoryList);
            //count
            Long sonCount  = sonCategoryList.stream().collect(Collectors.summingLong(Category::getCount));
            parentCategory.setCount( parentCategory.getCount() + sonCount);
        }
        return parentCategoryList;
    }

    @Override
    public void saveCategory(Category category) {
        //1，当前父分类下不能存在同名的子分类
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Category::getParentId, category.getParentId());
        queryWrapper.eq(Category::getName, category.getName());
        long count = count( queryWrapper );

        if ( count > 0) {
            throw new RuntimeException( "%s的父分类下，已经存在名为%s的子分类信息！添加失败".formatted(category.getParentId(),category.getName()));
        }
        //2.保存当前分类即可
        save(category);
    }


    /**
     * 更新分类信息
     * @param category
     */
    @Override
    public void updateCategory(Category category) {
        //1.校验同一个父类，不能与其他的子分类的name相同，可以和自己的原来的name相同
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Category::getParentId, category.getParentId());
        queryWrapper.eq(Category::getName, category.getName());
        queryWrapper.ne(Category::getId, category.getId());
        long count = count( queryWrapper);
        if ( count> 0 ) {
            throw new RuntimeException("%s父分类下，已经存在名为:%s的子分类信息，本次更新失败".formatted(category.getParentId(), category.getName()));
        }
        //2.更新分类信息
        updateById(category);

    }

    @Override
    public void removeCategory(Long id) {
        //1.判定是不是一级分类
        Category category = getById(id);
        if ( category == null) {
            log.debug( "在删除之前已经被删除");
            return;
        }
        if ( category.getParentId()==0) { //一级分类删除失败
            throw new RuntimeException("id= %s的分类为一级分类，不允许删除".formatted(id));
        }
        //2.判定有没有关联的题目
        LambdaQueryWrapper<Question> questionLambdaQueryWrapper= new LambdaQueryWrapper<>();
        questionLambdaQueryWrapper.eq(Question::getCategoryId, id);
        long count = questionMapper.selectCount(questionLambdaQueryWrapper);

        if ( count>0) { //有关联的题目，删除失败
            throw new RuntimeException("id=%s的分类删除失败，因为有关联的题目，关联的题目数量为:%s".formatted( id,count));
        }
        //3.才可以进行删除
        removeById(id);
    }

}